package com.yueyang.sojourn.server.common.baymax.web.resolver;

import com.yueyang.sojourn.server.common.baymax.web.resolver.spi.RestResponseMessageProvider;
import com.yueyang.sojourn.server.common.baymax.web.resolver.spi.imp.AbstractRestExceptionRestResponseMessageProvider;
import com.yueyang.sojourn.server.common.baymax.web.resolver.spi.imp.SpiRemoteCallExceptionRestResponseMessageProvider;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 从异常中解析要响应给客户端的信息
 */
/* PACKAGE */final class RestResponseMessageProviders {
  private RestResponseMessageProviders() {
    throw new UnsupportedOperationException();
  }

  private static final List<RestResponseMessageProvider> restMessageProviders =
      new CopyOnWriteArrayList<>();
  static {
    // 自动加载业务码解析器
//    ServiceLoader<RestResponseMessageProvider> providerLoader =
//        ServiceLoader.load(RestResponseMessageProvider.class);
//
//    if (providerLoader != null) {
//      Iterator<RestResponseMessageProvider> providerIterator =
//          providerLoader.iterator();
//      if (providerIterator != null) {
//        while (providerIterator.hasNext()) {
//          add(providerIterator.next());
//        }
//      }
//    }
    add(new AbstractRestExceptionRestResponseMessageProvider());
    add(new SpiRemoteCallExceptionRestResponseMessageProvider());

  }

  /**
   * 动态添加RestResponseMessage解析器，此方法是线程安全的
   * 
   * @author huisman
   */
  static void add(RestResponseMessageProvider provider) {
    if (provider == null) {
      return;
    }
    restMessageProviders.add(provider);
  }

  /**
   * 从异常中获取需要响应给客户端的信息
   * 
   * @return nerver return null
   */
  static com.yueyang.sojourn.server.common.baymax.web.resolver.RestResponseMessage getRestResponseMessage(Exception source) {
    if (source != null && !restMessageProviders.isEmpty()) {
      for (RestResponseMessageProvider provider : restMessageProviders) {
        if (provider.support(source)) {
          RestResponseMessage rr = provider.produce(source);
          if (rr == null) {
            continue;
          }
          return rr;
        }
      }
    }
    return null;
  }

  /**
   * 是否支持此种异常解析RestResponseMessage
   * 
   * @author huisman
   */
  static boolean support(Exception source) {
    if (source != null && !restMessageProviders.isEmpty()) {
      for (RestResponseMessageProvider provider : restMessageProviders) {
        if (provider.support(source)) {
          return true;
        }
      }
    }
    return false;
  }
}
